﻿using System;
using UnityEngine;

namespace ComponentSystem
{
    /// <summary>
    /// 组件
    /// </summary>
    public abstract class Component : Object, ISerializeToEntity, IState
    {
        /// <summary>
        /// 实例ID
        /// </summary>
        public long InstanceId { get; set; }

        /// <summary>
        /// 组件状态
        /// </summary>
        public UniversalEnum.State state { get; protected set; } = UniversalEnum.State.Init;

        /// <summary>
        /// 父组件
        /// </summary>
        public Component Parent { get; set; }

        /// <summary>
        /// 获取父组件 泛型
        /// </summary>
        public T GetParent<T>() where T : Component
        {
            return this.Parent as T;
        }

        /// <summary>
        /// 获取父组件 EntityCSharp
        /// </summary>
        public EntityCSharp EntityCSharp
        {
            get
            {
                return this.Parent as EntityCSharp;
            }
        }

        /// <summary>
        /// 类构造函数
        /// </summary>
        protected Component()
        {
            Constructor();
        }

        /// <summary>
        /// 自定义构造函数
        /// </summary>
        protected override void Constructor()
        {
            this.InstanceId = IdGenerater.GenerateId();
            this.Awake();
            this.Start();
            this.UpdateState(UniversalEnum.State.IsInited);
        }

        /// <summary>
        /// Awake
        /// </summary>
        protected override void Awake()
        {
            base.Awake();
        }

        /// <summary>
        /// 更新状态
        /// </summary>
        /// <param name="state">状态</param>
        /// <returns>状态</returns>
        protected UniversalEnum.State UpdateState(UniversalEnum.State state)
        {
            this.state = state;
            return this.state;
        }

        #region 状态管理

        public bool IsInit() => this.state == UniversalEnum.State.Init;
        public bool IsInited() => this.state == UniversalEnum.State.IsInited;
        public bool IsStart() => this.state == UniversalEnum.State.Start;
        public bool IsStop() => this.state == UniversalEnum.State.Stop;
        public bool IsPause() => this.state == UniversalEnum.State.Pause;
        public bool IsResume() => this.state == UniversalEnum.State.Resume;
        public bool IsReset() => this.state == UniversalEnum.State.Reset;
        public bool IsDisposed() => this.state == UniversalEnum.State.Disposed;

        /// <summary>
        /// Start
        /// </summary>
        protected override void Start()
        {
            base.Start();
            this.UpdateState(UniversalEnum.State.Start);
        }

        /// <summary>
        /// 销毁
        /// </summary>
        public virtual void Dispose()
        {
            if (this.IsDisposed())
            {
                return;
            }

            this.InstanceId = 0;
            this.UpdateState(UniversalEnum.State.Disposed);
        }
        public virtual void ReStart()
        {
            this.UpdateState(UniversalEnum.State.Start);
        }

        public virtual void Stop()
        {
            this.UpdateState(UniversalEnum.State.Stop);
        }

        public virtual void Pause()
        {
            this.UpdateState(UniversalEnum.State.Pause);
        }

        public virtual void Resume()
        {
            this.UpdateState(UniversalEnum.State.Resume);
        }

        public virtual void Reset()
        {
            this.UpdateState(UniversalEnum.State.Reset);
        }

        #endregion
    }
}